﻿package net.wangit.context;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MultiPartRequestWrapper extends HttpServletRequestWrapper {
	Collection<String> errors;
	MultiPartRequest multi;

	public MultiPartRequestWrapper(HttpServletRequest req) {
		super(req);
	}

	public MultiPartRequestWrapper(MultiPartRequest multiPartRequest,
			HttpServletRequest request) {
		super(request);

		this.multi = multiPartRequest;
		try {
			this.multi.parse(request);
			Iterator<String> localIterator = this.multi.getErrors().iterator();
			while (localIterator.hasNext()) {
				String o = localIterator.next();
				String error = o;
				addError(error);
			}
		} catch (IOException e) {
			addError("Cannot parse request: " + e.toString());
		}
	}

	public Enumeration<String> getFileParameterNames() {
		if (this.multi == null) {
			return null;
		}

		return this.multi.getFileParameterNames();
	}

	protected File[] getFiles(String fieldName) {
		if (this.multi == null) {
			return null;
		}

		return this.multi.getFile(fieldName);
	}

	public String[] getFileSystemNames(String fieldName) {
		if (this.multi == null) {
			return null;
		}

		return this.multi.getFilesystemName(fieldName);
	}

	public String getParameter(String name) {
		return (((this.multi == null) || (this.multi.getParameter(name) == null)) ? super
				.getParameter(name)
				: this.multi.getParameter(name));
	}

	public Map<String, String[]> getParameterMap() {
		Map<String, String[]> map = new HashMap<String, String[]>();
		Enumeration<String> enumeration = getParameterNames();

		while (enumeration.hasMoreElements()) {
			String name = (String) enumeration.nextElement();
			map.put(name, getParameterValues(name));
		}

		return map;
	}

	@SuppressWarnings("unchecked")
	public Enumeration<String> getParameterNames() {
		if (this.multi == null) {
			return super.getParameterNames();
		}
		return mergeParams(this.multi.getParameterNames(), super
				.getParameterNames());
	}

	public String[] getParameterValues(String name) {
		return (((this.multi == null) || (this.multi.getParameterValues(name) == null)) ? super
				.getParameterValues(name)
				: this.multi.getParameterValues(name));
	}

	public boolean hasErrors() {
		return ((this.errors != null) && (!(this.errors.isEmpty())));
	}

	public Collection<String> getErrors() {
		return this.errors;
	}

	protected void addError(String anErrorMessage) {
		if (this.errors == null) {
			this.errors = new ArrayList<String>();
		}

		this.errors.add(anErrorMessage);
	}

	protected Enumeration<String> mergeParams(Enumeration<String> params1,
			Enumeration<String> params2) {
		Vector<String> temp = new Vector<String>();

		while (params1.hasMoreElements()) {
			temp.add(params1.nextElement());
		}

		while (params2.hasMoreElements()) {
			temp.add(params2.nextElement());
		}

		return temp.elements();
	}
}